using System;
using HCore.Core;
using HCore.IOC.Beans.Factory;
using HCore.IOC.Beans.Factory.Attribute.Attr;
using HCore.IOC.Context.Attribute.Attr;
using HCore.IOC.Context.Event;
using HCore.IOC.Context.Stereotype;
using HCore.Unity.Manager.Support.Storage;

namespace HCore.Tests.Runtime.DianDianDian.Model
{
    public interface IGameModel
    {
        public int KillCount { get; set; }
        public int BestScore { get; set; }
        public int Gold { get; set; }
        public int Score { get; set; }
        public int GameStatus { get; set; }
        public int Life { get; set; }

        public void RegisterBestScoreChangedListener(Action<int, int> action);
        public void RegisterGoldChangedListener(Action<int, int> action);
        public void RegisterLifeChangedListener(Action<int, int> action);
        public void RegisterScoreChangedListener(Action<int, int> action);
        public void UnRegisterBestScoreChangedListener(Action<int, int> action);
        public void UnRegisterGoldChangedListener(Action<int, int> action);
        public void UnRegisterLifeChangedListener(Action<int, int> action);
        public void UnRegisterScoreChangedListener(Action<int, int> action);
    }

    [Primary]
    [Component]
    public class GameModel : EventPublisher, IGameModel, IInitializingBean
    {
        [Autowired] private IStorage mStorage;
        private BindableProperty<int> _BestScore { get; } = new();
        private BindableProperty<int> _Score { get; } = new();
        private BindableProperty<int> _Gold { get; } = new();
        private BindableProperty<int> _Life { get; } = new();

        // 1：游戏中；0：未开始
        public int GameStatus { get; set; } = 0;

        public int KillCount { get; set; } = 0;

        public int BestScore
        {
            get => _BestScore.Value;
            set => _BestScore.Value = value;
        }

        public int Gold
        {
            get => _Gold.Value;
            set => _Gold.Value = value;
        }

        public int Life
        {
            get => _Life.Value;
            set => _Life.Value = value;
        }

        public int Score
        {
            get => _Score.Value;
            set => _Score.Value = value;
        }

        public void RegisterBestScoreChangedListener(Action<int, int> action)
        {
            _BestScore.Register(action);
        }

        public void RegisterGoldChangedListener(Action<int, int> action)
        {
            _Gold.Register(action);
        }

        public void RegisterLifeChangedListener(Action<int, int> action)
        {
            _Life.Register(action);
        }

        public void RegisterScoreChangedListener(Action<int, int> action)
        {
            _Score.Register(action);
        }

        public void UnRegisterBestScoreChangedListener(Action<int, int> action)
        {
            _BestScore.UnRegister(action);
        }

        public void UnRegisterGoldChangedListener(Action<int, int> action)
        {
            _Gold.UnRegister(action);
        }

        public void UnRegisterLifeChangedListener(Action<int, int> action)
        {
            _Life.UnRegister(action);
        }

        public void UnRegisterScoreChangedListener(Action<int, int> action)
        {
            _Score.UnRegister(action);
        }

        public void AfterPropertiesSet()
        {
            _BestScore.Value = mStorage.GetValue(nameof(BestScore), 0);
            _BestScore.Register((value, _) => mStorage.SaveValue(nameof(BestScore), value));

            _Gold.Value = mStorage.GetValue(nameof(Gold), 0);
            _Gold.Register((value, _) => mStorage.SaveValue(nameof(Gold), value));
        }
    }
}